/*
 * AbstractElement.cpp
 *
 *  Created on: 2010-9-26
 *      Author: wenjian
 */

#include "AbstractElement.h"
#include "AbstractLayer.h"
#include "AbstractElements.h"

using namespace std;
using namespace Thk;
namespace Ed {

  AbstractElement::AbstractElement() :layer(NULL), _x(0), _y(0), _w(0), _h(0), redrawFlag(false),
  //boundRect(NULL),
  mouseHovering(false), mLeaveEvent(MouseEvent::LeaveType, this), mEnterEvent(MouseEvent::EnterType, this),
  selectEvent(this), selected(false), modifiedEvent(this), eventEnabled(true), paintEvent(this)
  {
    setModified(true);
  }
  AbstractElement::~AbstractElement() {

  }

  void AbstractElement::setCoordinate(real x, real y){
    if(_x ==x && _y==y){
      return;
    }
    _x = x;
    _y = y;
    setModified(true);
  }

  /**
   * 增量移动到目标位置
   */
  void AbstractElement::moveBy(real dx, real dy){
    setCoordinate(this->x()+dx, this->y()+dy);
    createPath();
  }

  void AbstractElement::setModified(bool b) {
    ModifiedSupport::setModified(b);
    //处理事件方法
    event(&modifiedEvent);
    //同步发送事件
    EventDispatcher::fire(&modifiedEvent);
  }

  void AbstractElement::setSelected(bool b, bool fireEvent){
    if(selected != b){
      selected = b;
      //向选择器发送改变选中状态事件
      if(fireEvent){
        selectEvent.setSelected(b);
        event(&selectEvent);
        EventSupport::fire(&selectEvent);
      }
      //设置此元素被修改标记
      setModified(true);
    }
  }

  /**
   * 设置焦点
   */
  void AbstractElement::setFocus(){
    if(layer){
      layer->setFocusElement(this);
    }
  }

  /**
   * 检查是否焦点层
   */
  bool AbstractElement::isFocus(){
    return layer && layer->getFocusElement() == this;
  }

  /**
   * 跟踪响应事件
   */
  bool AbstractElement::trackEvent(const Thk::Event* e){
    if(!isEventEnabled()){
      return false;
    }
    if(MouseEvent::isMouseEvent(e)){
      //如果是鼠标事件
      return handleMouseEvent((MouseEvent*)e);
    }else{
      return event(e);
    }
  }

  /**
   * 处理鼠标事件
   */
  bool AbstractElement::handleMouseEvent(const MouseEvent* me){
    //设置鼠标悬停状态
    mouseHovering = true;
    //在本元素中分发鼠标事件
    return event(me);
  }

  /**
   * 发送鼠标离开事件
   */
  bool AbstractElement::mouseLeave(){
    if(!mouseHovering){
      return true;
    }

    if(layer->getMouseHoveringElement() == this){
      mouseHovering = false;
      layer->clearMouseHoveringElement();
    }

    //向在此层上监听的对象发送鼠标离开事件
    return event(&mLeaveEvent);
  }

  /**
   * 发送鼠标进入元素事件
   */
  bool AbstractElement::mouseEnter(){
    return event(&mEnterEvent);
  }

//  /**
//   * 重画与此元素相交的其它元素, 排除<code>excludeds</code>中的元素
//   */
//  void AbstractElement::redrawIntersection(const std::vector<AbstractElement*>* excludeds){
//    prepareRedrawElements();
//    redrawElements->redrawIntersection((const std::vector<AbstractElement*>*)excludeds);
//  }
//
//  /**
//   * 重画与此元素相交的元素, 包括相交元素和自己, 排除<code>excludeds</code>中的元素
//   */
//  void AbstractElement::redrawAll(const std::vector<AbstractElement*>* excludeds){
//    prepareRedrawElements();
//    redrawElements->redrawAll((const std::vector<AbstractElement*>*)excludeds);
//  }
//
//  void  AbstractElement::prepareRedrawElements(){
//    if(!redrawElements){
//      redrawElements = new AbstractElements(this);
//      redrawElements->setLayer(layer);
//    }
//  }

}
